﻿using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Definitions;
using DotNetNuke.Entities.Portals;
using Aricie.DNN.Settings;
using Aricie.DNN.Modules.LuceneSearch.Business;
using Lucene.Net.Documents;
using Lucene.Net.Search.Highlight;

namespace Aricie.DNN.Services.Url.FriendlyUrl.Providers.DNN6
{
    //todo: current algorithm is smelly (no mid nor tabid will be provided in params)
    public class LuceneSearchUrlRewriter : IUrlRewriterProvider, IIsActive
    {

        private static Dictionary<string, UrlProviderInfo> _WrappedModuleRewriters = new Dictionary<string, UrlProviderInfo>();
        
        List<GroupParamsRewrite> IFriendlyUrlGroupProvider.GetRewrites()
        {

            List<GroupParamsRewrite> toReturn = new List<GroupParamsRewrite>();

            string desc = "search criteria component of the lucene search query, unescaped for Lucene Syntax";
            toReturn.Add(new GroupParamsRewrite("Search", desc, RewriteType.SubPath, UrlParam.FromSyntax("search")));
            desc = "Filter component of the lucene search query, unescaped for Lucene Syntax";
            toReturn.Add(new GroupParamsRewrite("Filter", desc, RewriteType.SubPath, UrlParam.FromSyntax("filter")));
            //modifié pour ne plus montrer les champs de type SORT_
            foreach (FieldDefinition fieldDef in (PortalQueryingDriver.GetCurrent()).GetSearchableFields())
            {
                GroupParamsRewrite toAdd = new GroupParamsRewrite("Lucene" + fieldDef.Id, desc, RewriteType.SubPath, UrlParam.FromSyntax("filter"));
                toAdd.UrlParams[UrlParam.FromSyntax("filter")] = ParamNature.NonExclusive | ParamNature.Mandatory;
                toReturn.Add(toAdd);
            }
            toReturn.AddRange(this.GetAdditionalRewrites());
            return toReturn;

        }

        public virtual IList<GroupParamsRewrite> GetAdditionalRewrites()
        {
            return new List<GroupParamsRewrite>();
        }


        public virtual bool GetSpecificRewrite(ref GroupRewriteResult result, string groupName, RewriteType objRewriteType, Dictionary<UrlParam, string> parameters, FriendlierUrlStrategy behaviour)
        {
            return false;
        }

        GroupRewriteResult IUrlRewriterProvider.RewriteParams(string groupName, RewriteType objRewriteType, Dictionary<UrlParam, string> parameters, FriendlierUrlStrategy behaviour)
        {

            GroupRewriteResult toReturn = new GroupRewriteResult();

            string param = string.Empty;
            string unescapedParam = string.Empty;

            switch (groupName.ToLowerInvariant())
            {
                case "search":
                    param = parameters[UrlParam.FromSyntax("search")];
                    unescapedParam = BusinessController.LuceneUnEscape(BusinessController.LuceneUnEscape(param));
                    toReturn.RewriteValue = unescapedParam;
                    toReturn.ConsumedParameters[UrlParam.FromSyntax("search")] = true;
                    break;
                default:
                    param = parameters[UrlParam.FromSyntax("filter")];
                    unescapedParam = BusinessController.LuceneUnEscape(BusinessController.LuceneUnEscape(param));
                    if (groupName.ToLowerInvariant() == "filter")
                    {
                        toReturn.RewriteValue = unescapedParam;
                        toReturn.ConsumedParameters[UrlParam.FromSyntax("filter")] = true;
                    }
                    else if ((groupName.ToLowerInvariant()).StartsWith("lucene"))
                    {
                        string fieldName = groupName.Substring(6);

                        if (!string.IsNullOrEmpty(unescapedParam))
                        {
                            Dictionary<string, WeightedTerm> terms = BusinessController.GetTerms(NukeHelper.PortalId, unescapedParam);
                            if (terms.ContainsKey(fieldName.ToLowerInvariant()))
                            {
                                string value = GetTermValue(fieldName.ToLowerInvariant(), terms);
                                if (!string.IsNullOrEmpty(value))
                                {
                                    toReturn.AddRewriteValue(value);
                                    string rangeField = fieldName + "2";
                                    if (terms.ContainsKey(rangeField))
                                    {
                                        toReturn.AddRewriteValue(GetTermValue(rangeField, terms));
                                    }
                                }
                                toReturn.ConsumedParameters[UrlParam.FromSyntax("filter")] = true;
                            }
                        }
                    }

                    break;
            }

            return toReturn;
        }

        protected virtual string GetTermValue(string fieldName, Dictionary<string, WeightedTerm> terms)
        {
            string value = ((WeightedTerm)terms[fieldName]).Term;
            string indexedDate = LuceneGeneralField.IndexedDate.ToLowerInvariant();
            string pubDate = DnnSearchItemField.PubDate.ToLowerInvariant();
            if (fieldName.ToLowerInvariant() == pubDate || fieldName.ToLowerInvariant() == (pubDate + "2") 
                || fieldName.ToLowerInvariant() == indexedDate || fieldName.ToLowerInvariant() == (indexedDate + "2"))
            {
                value = DateTools.StringToDate(value).ToString("ddMMyy");
            }
            return value;
        }


        public bool IsActive
        {
            get { return DotNetNuke.Framework.Reflection.CreateType("Aricie.DNN.Modules.LuceneSearch.Business.BusinessController", true) != null; }
        }
    }
}